package hu.jonas.allunit.views;

import hu.jonas.allunit.AllUnitPlugin;
import hu.jonas.allunit.model.TestResult;
import hu.jonas.allunit.model.TestResultModel;
import hu.jonas.allunit.source.JavaUtils;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.junit.JUnitCore;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;

public class AllUnitViewPart extends ViewPart {

	public static final String VIEWPART_ID = "hu.jonas.allunit.testresults";
	
	private ProgressPanel progressPanel;
	private TableViewer testTable;
	private TestResultSorter testResultSorter = new TestResultSorter();
	private AllUnitTestRunListener testRunListener;
	private Map<IProject, Integer> numberOfTests = new HashMap<IProject, Integer>();

	public AllUnitViewPart() {
	}

	@Override
	public void createPartControl(Composite parent) {

		TestResultModel testResultModel = AllUnitPlugin.getTestResultModel();

		GridLayout layout = new GridLayout();
		parent.setLayout(layout);

		progressPanel = new ProgressPanel(parent, SWT.NONE);
		progressPanel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
		testResultModel.setProgressPanel(progressPanel);
		
		testTable = createTestResultTable(parent);
		testTable.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		testResultModel.setViewer(testTable);
		
		testRunListener = new AllUnitTestRunListener();
		JUnitCore.addTestRunListener(testRunListener);
	}

	@Override
	public void setFocus() {
	}

	@Override
	public void dispose() {
		JUnitCore.removeTestRunListener(testRunListener);
		super.dispose();
	}

	public void initializeBeforeRunTests() {
		int total = 0;
		for (int testCount : numberOfTests.values()) {
			total += testCount;
		}
		testRunListener.initializeBeforeRunSessions(total);
	}
	
	public void initializeBeforeRunTests(int typeCount) {
		testRunListener.initializeBeforeRunSessions(typeCount);
	}

	public void setNumberOfTests(IProject project, int numberOfClasses) {
		numberOfTests.put(project, numberOfClasses);
	}
	
	public TableViewer getTestResultTable() {
		return testTable;
	}
	
	public ProgressPanel getProgressPanel() {
		return progressPanel;
	}
	
	private TableViewer createTestResultTable(Composite parent) {

		TableViewer result = new TableViewer(parent, SWT.FULL_SELECTION);

		String[] headers = new String[] { "Test class", "Test method", "Elapsed time" };
		int[] widths = new int[] { 300, 250, 150 };
		
		for (int i = 0; i < headers.length; i++) {
			TableViewerColumn column = new TableViewerColumn(result, SWT.NONE);
			final TableColumn tableColumn = column.getColumn();
			final int columnNumber = i;

			tableColumn.setText(headers[i]);
			tableColumn.setWidth(widths[i]);
			tableColumn.addSelectionListener(new SelectionAdapter() {

				@Override
				public void widgetSelected(SelectionEvent e) {
					Table table = testTable.getTable();
					int sortDirection = table.getSortDirection();
					
					if (table.getSortColumn() == tableColumn) {
						table.setSortDirection(sortDirection == SWT.UP ? SWT.DOWN : SWT.UP);
						testResultSorter.setSortDirection(-1 * testResultSorter.getSortDirection());
					} else {
						table.setSortColumn(tableColumn);
						table.setSortDirection(SWT.UP);
						testResultSorter.setSortColumn(columnNumber);
						testResultSorter.setSortDirection(1);
					}
					
					testTable.refresh();
				}
				
			});
		}
		
		
		//column.getColumn().setAlignment(SWT.RIGHT);

		result.getTable().setHeaderVisible(true);
		result.getTable().setLinesVisible(true);
		result.setLabelProvider(new TestResultTableLabelProvider());
		result.setContentProvider(new TestResultContentProvider());
		result.setSorter(testResultSorter);

		result.addDoubleClickListener(new IDoubleClickListener() {

			@Override
			public void doubleClick(DoubleClickEvent event) {
				ISelection selection = event.getSelection();

				if (selection.isEmpty()) {
					return;
				}

				if (selection instanceof StructuredSelection) {
					StructuredSelection structuredSelection = (StructuredSelection) selection;
					TestResult firstElement =
						(TestResult) structuredSelection.getFirstElement();

					IMethod method = JavaUtils.findJavaMethodByName(
							firstElement.getTestClassName(),
							firstElement.getTestMethodName()
						);

					try {
						JavaUtils.openEditorWithJavaMethod(method);
					} catch (PartInitException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (JavaModelException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

			}
		});

		return result;
	}

}
